﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
 * 版权所有 (c) 2022 北京超维景生物科技有限公司 保留所有权利。
 * 
 * 创建者：huangyang
 * 电子邮箱：huangyang@tvscope.cn
 * 创建时间：2023/2/23 11:50:14
 * 版本：V1.0.0
 * 描述：
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 注 释 >>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ImageK.Java;
using ImageK.Macros;
using ImageK.Plugin;
using ImageK.Plugin.Frame;
using ImageK.Process;
using ImageK.Util;

namespace ImageK.Gui
{
	/** This class is a rectangular ROI containing text. */
	public class TextRoi : Roi
	{

	    public const int LEFT = 0, CENTER = 1, RIGHT = 2;
	    const int MAX_LINES = 50;

	    private const string line1 = "Enter text, then press";
	    private const string line2 = "ctrl+b to add to overlay";
	    private const string line3 = "or ctrl+d to draw.";
	    private const string line1a = "Enter text...";
	    private string[] theText = new string[MAX_LINES];
	    private static string name = "SansSerif";
	    private static FontStyle style = FontStyle.Regular;
	    private static int size = 18;
	    private Font font;
	    private static bool antialiasedText = true; // global flag used by text tool
	    private static int globalJustification = LEFT;
	    private static Color defaultFillColor;
	    private int justification = LEFT;
	    private double previousMag;
	    private bool firstChar = true;
	    private bool firstMouseUp = true;
	    private double angle;  // degrees
	    private static double defaultAngle;
	    private static bool firstTime = true;
	    private Roi previousRoi;
	    private Graphics fontGraphics;
	    private static Font defaultFont = IJ.font12;
        private Brush _brush;
        private Pen _pen;

	    /** Creates a TextRoi using the defaultFont.*/
	    public TextRoi(int x, int y, String text) : this(x, y, text, defaultFont)
	    {
		   
	    }

	    /** Use this constructor as a drop-in replacement for ImageProcessor.drawString(). */
	    public TextRoi(String text, double x, double y, Font font): base(x, y, 1, 1)
		    {
		    ;
		    init(text, font);
		    if (font != null)
		    {
			    Graphics g = getFontGraphics(font);
			    FontMetrics metrics = new FontMetrics(g, font);
			    RectangleF fbounds = getFloatBounds();
			    fbounds.Y = fbounds.Y - metrics.getAscent();
			    setBounds(fbounds);
		    }
	    }

	    /** Creates a TextRoi using sub-pixel coordinates.*/
	    public TextRoi(double x, double y, String text): base(x, y, 1.0, 1.0)
	    {
		    
		    init(text, null);
	    }

	    /** Creates a TextRoi using the specified location and Font.
	     * @see ij.gui.Roi#setStrokeColor
	     * @see ij.gui.Roi#setNonScalable
	     * @see ij.ImagePlus#setOverlay(ij.gui.Overlay)
	     */
	    public TextRoi(int x, int y, string text, Font font): base(x, y, 1, 1)
	    {
		    
		    init(text, font);
	    }

	    /** Creates a TextRoi using the specified sub-pixel location and Font. */
	    public TextRoi(double x, double y, string text, Font font): base(x, y, 1.0, 1.0)
	    {
		    
		    init(text, font);
	    }

	    /** Creates a TextRoi using the specified sub-pixel location, size and Font. */
	    public TextRoi(double x, double y, double width, double height, string text, Font font): base(x, y, width, height)
	    {
		    
		    init(text, font);
	    }

	    /** Creates a TextRoi using the specified text and location. */
	    public static TextRoi create(String text, double x, double y, Font font)
	    {
		    return new TextRoi(text, x, y, font);
	    }

	    /** Obsolete. */
	    public static TextRoi create(double x, double y, String text, Font font)
	    {
		    return new TextRoi(x, y, text, font);
	    }

	    private void init(String text, Font font)
	    {
		    string[] lines = text.Split("\n");
		    int count = Math.Min(lines.Length, MAX_LINES);
		    for (int i = 0; i < count; i++)
			    theText[i] = lines[i];
		    if (font == null)
			    font = defaultFont;
		    if (font == null)
			    font = ImageK.SansSerif14;
		    this.font = font;
		    // setAntiAlias(antialiasedText);
		    firstChar = false;
		    if (defaultColor != null)
			    setStrokeColor(defaultColor);
		    updateBounds();
	    }

	    /** @deprecated */
	    public TextRoi(int x, int y, String text, Font font, Color color): base(x, y, 1, 1)
	    {
		    
		    if (font == null) font = new Font(name, size, style);
		    this.font = font;
		    IJ.error("TextRoi", "API has changed. See updated example at\nhttp://imagej.nih.gov/ij/macros/js/TextOverlay.js");
	    }

	    public TextRoi(int x, int y, ImagePlus imp): base(x, y, imp)
	    {
		    
		    ImageCanvas ic = imp.getCanvas();
		    double mag = getMagnification();
		    if (mag > 1.0)
			    mag = 1.0;
		    if (size < (12 / mag))
			    size = (int)(12 / mag);
		    if (firstTime)
		    {
			    theText[0] = line1;
			    theText[1] = line2;
			    theText[2] = line3;
			    firstTime = false;
		    }
		    else
			    theText[0] = line1a;
		    if (previousRoi != null && (previousRoi is TextRoi)) {
			    firstMouseUp = false;
			    previousRoi = null;
		    }
		    font = new Font(name, size, style);
		    justification = globalJustification;
		    setStrokeColor(ToolBar.getForegroundColor());
		    // setAntiAlias(antialiasedText);
		    if (WindowManager.getWindow("Fonts") != null)
		    {
			    setFillColor(defaultFillColor);
			    setAngle(defaultAngle);
		    }
	    }

	    /** This method is used by the text tool to add typed
		    characters to displayed text selections. */
	    public void addChar(char c)
	    {
		    if (imp == null) return;
		    if (!(c >= ' ' || c == '\b' || c == '\n')) return;
		    int cline = 0;
		    if (firstChar)
		    {
			    theText[cline] = new String("");
			    for (int i = 1; i < MAX_LINES; i++)
				    theText[i] = null;
		    }
		    else
		    {
			    for (int i = 0; i < theText.Length && theText[i] != null; i++)
				    cline = i; //add the character to the last line
		    }
		    if ((int)c == '\b')
		    {
			    // backspace
			    if (theText[cline].Length > 0)
				    theText[cline] = theText[cline].Substring(0, theText[cline].Length - 1);
			    else if (cline > 0)
			    {
				    theText[cline] = null;
				    cline--;
			    }
			    if (angle != 0.0)
				    imp.draw();
			    else
				    imp.draw(clipX, clipY, clipWidth, clipHeight);
			    firstChar = false;
			    return;
		    }
		    else if ((int)c == '\n')
		    {
			    // newline
			    if (cline < (MAX_LINES - 1)) cline++;
			    theText[cline] = "";
			    updateBounds();
			    updateText();
		    }
		    else
		    {
			    char[] chr = { c };
			    theText[cline] += new String(chr);
			    updateBounds();
			    updateText();
			    firstChar = false;
			    return;
		    }
	    }

	    Font getScaledFont()
	    {
		    if (font == null)
			    font = ImageK.SansSerif14;
		    double mag = getMagnification();
		    if (nonScalable || imp == null || mag == 1.0)
			    return font;
		    else
			    return font.deriveFont((float)(font.Size * mag));
	    }

	    /** Renders the text on the image. Draws the text in
	     * the foreground color if ip.setColor(Color) has
	     * not been called.
	     *	@see ij.process.ImageProcessor#setFont(Font)
	     *	@see ij.process.ImageProcessor#setAntialiasedText(boolean)
	     *	@see ij.process.ImageProcessor#setColor(Color)
	    */
	    public void drawPixels(ImageProcessor ip)
	    {
		    if (!ip.fillValueSet())
			    ip.setColor(ToolBar.getForegroundColor());
		    ip.setFont(font);
		    ip.setAntialiasedText(getAntiAlias());
		    FontMetrics metrics = ip.getFontMetrics();
		    int fontHeight = metrics.getHeight();
		    int descent = metrics.getDescent();
		    int i = 0;
		    int yy = 0;
		    int xi = (int)Math.Round(getXBase());
		    int yi = (int)Math.Round(getYBase());
		    while (i < MAX_LINES && theText[i] != null)
		    {
			    switch (justification)
			    {
				    case LEFT:
					    ip.drawString(theText[i], xi, yi + yy + fontHeight);
					    break;
				    case CENTER:
					    int tw = (int)metrics.StringWidth(theText[i]);
					    ip.drawString(theText[i], xi + (this.width - tw) / 2, yi + yy + fontHeight);
					    break;
				    case RIGHT:
					    tw = (int)metrics.StringWidth(theText[i]);
					    ip.drawString(theText[i], xi + this.width - tw, yi + yy + fontHeight);
					    break;
			    }
			    i++;
			    yy += fontHeight;
		    }
	    }

	    /** Draws the text on the screen, clipped to the ROI. */
	    public override void draw(Graphics g)
	    {
		    if (IJ.debugMode) IJ.log("draw: " + theText[0] + "  " + this.width + "," + this.height);
		    if (Interpreter.isBatchMode() && ic != null && ic.getDisplayList() != null)
			    return;
		    Color c = getStrokeColor();
		    setStrokeColor(getColor());
		    base.draw(g); // draw the rectangle
		    setStrokeColor(c);
		    double mag = getMagnification();
		    int sx = screenXD(getXBase());
		    int sy = screenYD(getYBase());
		    int swidth = (int)((bounds != null ? bounds.Width : this.width) * mag);
		    int sheight = (int)((bounds != null ? bounds.Height : this.height) * mag);
		    Rectangle r = Rectangle.Empty;
		    if (angle != 0.0)
			    drawText(g);
		    else
		    {
				//todo:
			    // r = g.getClipBounds();
			    // g.setClip(sx, sy, swidth, sheight);
			    drawText(g);
			    // if (r != null)
				   //  g.setClip(r.x, r.y, r.width, r.height);
		    }
	    }

	    public override void drawOverlay(Graphics g)
	    {
		    drawText(g);
	    }

	    public void drawText(Graphics g)
        {
            var localColor = strokeColor != Color.Empty ? strokeColor : ROIColor;
            _brush = new SolidBrush(localColor);
            _pen = new Pen(localColor);
            // g.setColor(strokeColor != Color.Empty ? strokeColor : ROIColor);
		    // Java2.setAntialiasedText(g, getAntiAlias());
		    double mag = getMagnification();
		    int xi = (int)Math.Round(getXBase());
		    int yi = (int)Math.Round(getYBase());
		    double widthd = bounds != null ? bounds.Width : this.width;
		    double heightd = bounds != null ? bounds.Height : this.height;
		    int widthi = (int)Math.Round(widthd);
		    int heighti = (int)Math.Round(heightd);
		    Font font = getScaledFont();
		    FontMetrics metrics = new FontMetrics(g, font);
		    int fontHeight = metrics.getHeight();
		    int descent = metrics.getDescent();
		    // g.setFont(font);
		    // Graphics2D g2d = (Graphics2D)g;
		    int sx = nonScalable ? xi : screenXD(getXBase());
		    int sy = nonScalable ? yi : screenYD(getYBase());
		    int sw = nonScalable ? widthi : (int)(getMagnification() * widthd);
		    int sh = nonScalable ? heighti : (int)(getMagnification() * heightd);
		    // AffineTransform at = null;
		    if (angle != 0.0)
		    {
			    // at = g2d.getTransform();
			    double cx = sx, cy = sy;
			    // double theta = Math.toRadians(angle);
			    // g2d.rotate(-theta, cx, cy);
		    }
		    int i = 0;
		    if (fillColor != Color.Empty)
		    {
			    // Color c = g.getColor();
			    int alpha = fillColor.A;
			    // g.setColor(fillColor);
                _brush = new SolidBrush(fillColor);
			    g.FillRectangle(_brush, sx, sy, sw, sh);
                _brush = new SolidBrush(localColor);
                // g.setColor(c);
		    }
		    while (i < MAX_LINES && theText[i] != null)
		    {
			    switch (justification)
			    {
				    case LEFT:
					    // g.DrawString(theText[i],font,_brush,sx, sy + fontHeight - descent);
					    g.DrawString(theText[i],font,_brush,sx, sy - descent);
					    break;
				    case CENTER:
					    int tw = (int)metrics.StringWidth(theText[i]);
					    // g.DrawString(theText[i],font, _brush, sx + (sw - tw) / 2, sy + fontHeight - descent);
					    g.DrawString(theText[i],font, _brush, sx + (sw - tw) / 2, sy - descent);
					    break;
				    case RIGHT:
					    tw = (int)metrics.StringWidth(theText[i]);
					    // g.DrawString(theText[i], font, _brush, sx + sw - tw, sy + fontHeight - descent);
					    g.DrawString(theText[i], font, _brush, sx + sw - tw, sy - descent);
					    break;
			    }
			    i++;
			    sy += fontHeight;
		    }
		    // if (at != null)  // restore transformation matrix used to rotate text
			   //  g2d.setTransform(at);
	    }

	    /** Returns the name of the default font. Use getCurrentFont().getName()
		     to get the name of the font that this TextRoi is using. */
	    public static String getDefaultFontName()
	    {
		    return name;
	    }

	    /** Returns the default font size. Use getCurrentFont().getSize()
		     to get the size of the font that this TextRoi is using. */
	    public static int getDefaultFontSize()
	    {
		    return size;
	    }

	    /** Returns the default font style. Use getCurrentFont().getStyle()
		     to get the style of the font that this TextRoi is using. */
	    public static FontStyle getDefaultFontStyle()
	    {
		    return style;
	    }

	    /** Sets the current font. */
	    public void setFont(Font font)
	    {
		    this.font = font;
		    updateBounds();
	    }

	    /** Sets the size of the current font. */
	    public void setFontSize(int size)
	    {
		    if (font == null)
			    font = defaultFont;
		    font = font.deriveFont((float)size);
	    }

	    /** Returns the current font. */
	    public Font getCurrentFont()
	    {
		    return font;
	    }

	    /** Returns the state of the global 'antialiasedText' variable, which is used by the "Fonts" widget. */
	    public static bool isAntialiased()
	    {
		    return antialiasedText;
	    }

	    /** Sets the state of the global 'antialiasedText' variable. */
	    public static void setAntialiasedText(bool antialiased)
	    {
		    antialiasedText = antialiased;
	    }

	    /** Sets the 'antiAlias' instance variable. */
	    public void setAntialiased(bool antiAlias)
	    {
		    setAntiAlias(antiAlias);
		    if (angle > 0.0)
			    setAntiAlias(true);
	    }

	    /** Returns the state of the 'antiAlias' instance variable. */
	    public bool getAntialiased()
	    {
		    return getAntiAlias();
	    }

	    /** Sets the default text tool justification (LEFT, CENTER or RIGHT). */
	    public static void setGlobalJustification(int justification)
	    {
		    if (justification < 0 || justification > RIGHT)
			    justification = LEFT;
		    globalJustification = justification;
		    ImagePlus imp = WindowManager.getCurrentImage();
		    if (imp != null)
		    {
			    Roi roi = imp.getRoi();
			    if (roi is TextRoi) {
				    ((TextRoi)roi).setJustification(justification);
				    imp.draw();
			    }
		    }
	    }

	    /** Returns the default text tool justification (LEFT, CENTER or RIGHT). */
	    public static int getGlobalJustification()
	    {
		    return globalJustification;
	    }

	    /** Sets the 'justification' instance variable (LEFT, CENTER or RIGHT) */
	    public void setJustification(int justification)
	    {
		    if (justification < 0 || justification > RIGHT)
			    justification = LEFT;
		    this.justification = justification;
		    updateBounds();
		    if (imp != null)
			    imp.draw();
	    }

	    /** Returns the value of the 'justification' instance variable (LEFT, CENTER or RIGHT). */
	    public int getJustification()
	    {
		    return justification;
	    }

	    /** Sets the global font face, size and style that will be used by
		    TextROIs interactively created using the text tool. */
	    public static void setFont(string fontName, int fontSize, FontStyle fontStyle)
	    {
		    setFont(fontName, fontSize, fontStyle, true);
	    }

	    /** Sets the font face, size, style and antialiasing mode that will 
		    be used by TextROIs interactively created using the text tool. */
	    public static void setFont(string fontName, int fontSize, FontStyle fontStyle, bool antialiased)
	    {
		    name = fontName;
		    size = fontSize;
		    style = fontStyle;
		    globalJustification = LEFT;
		    antialiasedText = antialiased;
		    ImagePlus imp = WindowManager.getCurrentImage();
		    if (imp != null)
		    {
			    Roi roi = imp.getRoi();
			    if (roi is TextRoi) {
				    roi.setAntiAlias(antialiased);
				    ((TextRoi)roi).setCurrentFont(new Font(name, size, style));
				    imp.draw();
			    }
		    }

	    }

	    /** Sets the default font. */
	    public static void setDefaultFont(Font font)
	    {
		    defaultFont = font;
	    }

	    /** Sets the default font size. */
	    public static void setDefaultFontSize(int size)
	    {
		    defaultFont = defaultFont.deriveFont((float)size);
	    }

	    /** Sets the default fill (background) color. */
	    public static void setDefaultFillColor(Color fillColor)
	    {
		    defaultFillColor = fillColor;
	    }

	    /** Sets the default angle. */
	    public static void setDefaultAngle(double angle)
	    {
		    defaultAngle = angle;
	    }

	    public override void handleMouseUp(int screenX, int screenY)
	    {
		    base.handleMouseUp(screenX, screenY);
		    if (this.width < 5 && this.height < 5 && imp != null && previousRoi == null)
		    {
			    int ox = ic != null ? ic.offScreenX(screenX) : screenX;
			    int oy = ic != null ? ic.offScreenY(screenY) : screenY;
			    TextRoi roi = new TextRoi(ox, oy, line1a);
			    roi.setStrokeColor(ToolBar.getForegroundColor());
			    roi.firstChar = true;
			    imp.setRoi(roi);
			    return;
		    }
		    else if (firstMouseUp)
		    {
			    updateBounds();
			    updateText();
			    firstMouseUp = false;
		    }
		    if (this.width < 5 || this.height < 5)
			    imp.deleteRoi();
	    }

	    /** Increases the size of bounding rectangle so it's large enough to hold the text. */
	    private void updateBounds()
	    {
		    if (firstChar)
			    return;
		    double lineHeight = 0;
		    double mag = getMagnification();
		    Font font = getScaledFont();
		    Graphics g = getFontGraphics(font);
		    // Java2.setAntialiasedText(g, getAntiAlias());
            FontMetrics metrics = new FontMetrics(g, font); // g.getFontMetrics(font);
		    double fontHeight = metrics.getHeight() / mag;
		    int i = 0, nLines = 0;
		    RectangleF b = getFloatBounds();
		    double newWidth = 10;
		    while (i < MAX_LINES && theText[i] != null)
		    {
			    nLines++;
			    double w = stringWidth(theText[i], metrics, g) / mag;
			    if (w > newWidth)
				    newWidth = w;
			    i++;
		    }
		    newWidth += 2.0;
		    b.Width = (float)newWidth;
		    switch (justification)
		    {
			    case LEFT:
				    break;
			    case CENTER:
				    b.X = (float)(this.oldX + this.oldWidth - newWidth / 2.0);
				    break;
			    case RIGHT:
				    b.X = (float)(this.oldX + this.oldWidth - newWidth);
				    break;
		    }
		    b.Height = (float)(nLines * fontHeight + 2);
		    setBounds(b);
	    }

	    private Graphics getFontGraphics(Font font)
	    {
		    if (fontGraphics == null)
		    {
                Bitmap bitmap = new Bitmap(1, 1); // 1x1像素足够用于测量
                fontGraphics = Graphics.FromImage(bitmap);
                // BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
                // fontGraphics = (Graphics2D)bi.getGraphics();

            }
		    // fontGraphics.setFont(font);
		    return fontGraphics;
	    }

	    void updateText()
	    {
		    if (imp != null)
		    {
			    updateClipRect();
			    if (angle != 0.0)
				    imp.draw();
			    else
				    imp.draw(clipX, clipY, clipWidth, clipHeight);
		    }
	    }

	    double stringWidth(string s, FontMetrics metrics, Graphics g)
        {
            var m = new FontMetrics(g, metrics.Font);
            return m.StringWidth(s);
			// java.awt.geom.Rectangle2D r = metrics.getStringBounds(s, g);
		 //    return r.getWidth();
	    }

	    /** Used by the Recorder for recording the text tool. */
	    public string getMacroCode(String cmd, ImagePlus imp)
	    {
		    string code = "";
		    bool script = Recorder.scriptMode();
		    bool addSelection = cmd.StartsWith("Add");
		    if (script && !addSelection)
			    code += "ip = imp.getProcessor();\n";
		    if (script)
		    {
			    string str = "Font.PLAIN";
			    if (style == FontStyle.Bold)
				    str = "Font.BOLD";
			    else if (style == FontStyle.Italic)
				    str = "Font.ITALIC";
			    code += "font = new Font(\"" + name + "\", " + str + ", " + size + ");\n";
			    if (addSelection)
				    return getAddSelectionScript(code);
			    code += "ip.setFont(font);\n";
		    }
		    else
		    {
			    String options = "";
			    if (style == FontStyle.Bold)
				    options += "bold";
			    if (style == FontStyle.Italic)
				    options += " italic";
			    if (antialiasedText)
				    options += " antialiased";
			    if (options.Equals(""))
				    options = "plain";
			    code += "setFont(\"" + name + "\", " + size + ", \"" + options + "\");\n";
		    }
		    ImageProcessor ip = imp.getProcessor();
		    ip.setFont(new Font(name, size, style));
		    FontMetrics metrics = ip.getFontMetrics();
		    int fontHeight = metrics.getHeight();
		    if (script)
			    code += "ip.setColor(new Color(" + getColorArgs(getStrokeColor()) + "));\n";
		    else
			    code += "setColor(\"" + Colors.colorToString(getStrokeColor()) + "\");\n";
		    if (addSelection)
		    {
			    code += "Overlay.drawString(\"" + text() + "\", " + this.x + ", " + (this.y + fontHeight) + ", " + getAngle() + ");\n";
			    code += "Overlay.show();\n";
		    }
		    else
		    {
			    code += (script ? "ip." : "") + "drawString(\"" + text() + "\", " + this.x + ", " + (this.y + fontHeight) + ");\n";
			    if (script)
				    code += "imp.updateAndDraw();\n";
			    else
				    code += "//makeText(\"" + text() + "\", " + this.x + ", " + (this.y + fontHeight) + ");\n";
		    }
		    return (code);
	    }

	    private string text()
	    {
		    string text = "";
		    for (int i = 0; i < MAX_LINES; i++)
		    {
			    if (theText[i] == null) break;
			    text += theText[i];
			    if (theText[i + 1] != null) text += "\\n";
		    }
		    return text;
	    }

	    private string getAddSelectionScript(string code)
	    {
		    code += "roi = new TextRoi(" + this.x + ", " + this.y + ", \"" + text() + "\", font);\n";
		    code += "roi.setStrokeColor(new Color(" + getColorArgs(getStrokeColor()) + "));\n";
		    if (getFillColor() != null)
			    code += "roi.setFillColor(new Color(" + getColorArgs(getFillColor()) + "));\n";
		    int just = getJustification();
		    if (just > LEFT)
		    {
			    if (just == CENTER)
				    code += "roi.setJustification(TextRoi.CENTER);\n";
			    else if (just == RIGHT)
				    code += "roi.setJustification(TextRoi.RIGHT);\n";
		    }
		    if (getAngle() != 0.0)
			    code += "roi.setAngle(" + getAngle() + ");\n";
		    code += "overlay.add(roi);\n";
		    return code;
	    }

	    private string getColorArgs(Color c)
	    {
		    return IJ.d2s(c.R / 255.0, 2) + ", " + IJ.d2s(c.G / 255.0, 2) + ", " + IJ.d2s(c.B / 255.0, 2);
	    }

	    public string getText()
	    {
		    string text = "";
		    for (int i = 0; i < MAX_LINES; i++)
		    {
			    if (theText[i] == null) break;
			    text += theText[i] + "\n";
		    }
		    return text;
	    }

	    public void setText(string text)
	    {
		    string[] lines = text.Split("\n");
		    bool changes = false;
		    for (int i = 0; i < Math.Min(lines.Length, theText.Length - 1); i++)
		    {
			    if (!lines[i].Equals(theText[i]))
			    {
				    theText[i] = lines[i];
				    changes = true;
			    }
		    }
		    if (lines.Length < theText.Length && theText[lines.Length] != null)
		    {
			    theText[lines.Length] = null;
			    changes = true;
		    }
		    if (changes)
		    {
			    firstChar = false;
			    updateBounds();
		    }
	    }

	    public bool isDrawingTool()
	    {
		    return true;
	    }

	    public void clear(ImageProcessor ip)
	    {
		    if (font == null)
			    ip.fill();
		    else
		    {
			    ip.setFont(font);
			    ip.setAntialiasedText(antialiasedText);
			    int i = 0, w = 0;
			    while (i < MAX_LINES && theText[i] != null)
			    {
				    int w2 = ip.getStringWidth(theText[i]);
				    if (w2 > w) ;
				    w = w2;
				    i++;
			    }
			    Rectangle r = ip.getRoi();
			    if (w > r.Width)
			    {
				    r.Width = w;
				    ip.setRoi(r);
			    }
			    ip.fill();
		    }
	    }

	
	    public override void setLocation(int x, int y)
	    {
		    base.setLocation(x, y);
		    oldWidth = this.width;
	    }

	    /** Returns a copy of this TextRoi. */
	    public object clone()
	    {
		    TextRoi tr = (TextRoi)base.clone();
		    tr.theText = new string[MAX_LINES];
		    for (int i = 0; i < MAX_LINES; i++)
			    tr.theText[i] = theText[i];
		    return tr;
	    }

	    public double getAngle()
	    {
		    return angle;
	    }

	    public void setAngle(double angle)
	    {
		    this.angle = angle;
		    if (angle != 0.0)
			    setAntiAlias(true);
	    }

	    public bool getDrawStringMode()
	    {
		    return false;
	    }

	    public void setDrawStringMode(bool drawStringMode)
	    {
	    }

	    public void setPreviousTextRoi(Roi previousRoi)
	    {
		    this.previousRoi = previousRoi;
	    }

	    /** @deprecated Replaced by getDefaultFontName */
	    public static string getFont()
	    {
		    return name;
	    }

	    /** @deprecated Replaced by getDefaultFontSize */
	    public static int getSize()
	    {
		    return size;
	    }

	    /** @deprecated Replaced by getDefaultFontStyle */
	    public static FontStyle getStyle()
	    {
		    return style;
	    }

	    /** @deprecated Replaced by setFont(font) */
	    public void setCurrentFont(Font font)
	    {
		    this.font = font;
		    updateBounds();
	    }
    }

}
